from typing import List, Optional, Dict, Any, Tuple
from datetime import datetime, timedelta
from models.sleep_monitoring import SleepMonitoringRecord, Room
from service.base_service import BaseService
import uuid
import json


class SleepMonitoringService(BaseService):
    """
    睡眠监测服务
    负责睡眠监测会话的创建、数据存储和分析
    """
    
    def __init__(self):
        super().__init__()
        self.model = SleepMonitoringRecord
    
    async def create_session(self, room_id: str, start_time: datetime = None) -> SleepMonitoringRecord:
        """
        创建新的监测会话
        
        Args:
            room_id: 房间ID
            start_time: 开始时间，默认为当前时间
            
        Returns:
            SleepMonitoringRecord: 创建的会话记录
        """
        if start_time is None:
            start_time = datetime.now()
        
        session_id = str(uuid.uuid4())
        
        session = SleepMonitoringRecord.create(
            session_id=session_id,
            room_id=room_id,
            start_time=start_time,
            end_time=start_time,  # 初始设置为开始时间
            total_seconds=0
        )
        
        self.logger.info(f"创建监测会话: {session_id} in room {room_id}")
        return session
    
    async def end_session(self, session_id: str, end_time: datetime = None) -> Optional[SleepMonitoringRecord]:
        """
        结束监测会话
        
        Args:
            session_id: 会话ID
            end_time: 结束时间，默认为当前时间
            
        Returns:
            Optional[SleepMonitoringRecord]: 更新后的会话记录
        """
        session = await self.get_session_by_id(session_id)
        if not session:
            return None
        
        if end_time is None:
            end_time = datetime.now()
        
        session.end_time = end_time
        session.total_seconds = int((end_time - session.start_time).total_seconds())
        
        # 计算摘要信息
        session.calculate_summary()
        session.save()
        
        self.logger.info(f"结束监测会话: {session_id}")
        return session
    
    async def get_session_by_id(self, session_id: str) -> Optional[SleepMonitoringRecord]:
        """
        根据会话ID获取会话记录
        
        Args:
            session_id: 会话ID
            
        Returns:
            Optional[SleepMonitoringRecord]: 会话记录
        """
        try:
            return SleepMonitoringRecord.get(SleepMonitoringRecord.session_id == session_id)
        except SleepMonitoringRecord.DoesNotExist:
            return None
    
    async def get_room_sessions(self, room_id: str, limit: int = 50, offset: int = 0) -> List[SleepMonitoringRecord]:
        """
        获取房间的监测会话列表
        
        Args:
            room_id: 房间ID
            limit: 限制数量
            offset: 偏移量
            
        Returns:
            List[SleepMonitoringRecord]: 会话记录列表
        """
        return list(
            SleepMonitoringRecord.select()
            .where(SleepMonitoringRecord.room_id == room_id)
            .order_by(SleepMonitoringRecord.start_time.desc())
            .limit(limit)
            .offset(offset)
        )
    
    async def add_processed_data(self, session_id: str, timestamp: int, 
                               state: str, confidence: float,
                               delta_ratio: float, theta_ratio: float,
                               alpha_ratio: float, beta_ratio: float,
                               gamma_ratio: float) -> bool:
        """
        添加处理后的脑波数据
        
        Args:
            session_id: 会话ID
            timestamp: 时间戳
            state: 用户状态
            confidence: 置信度
            delta_ratio: Delta波比例
            theta_ratio: Theta波比例
            alpha_ratio: Alpha波比例
            beta_ratio: Beta波比例
            gamma_ratio: Gamma波比例
            
        Returns:
            bool: 是否添加成功
        """
        session = await self.get_session_by_id(session_id)
        if not session:
            return False
        
        # 获取现有数据
        states_data = session.get_states_data()
        confidence_data = session.get_confidence_data()
        delta_data = session.get_delta_ratio_data()
        theta_data = session.get_theta_ratio_data()
        alpha_data = session.get_alpha_ratio_data()
        beta_data = session.get_beta_ratio_data()
        gamma_data = session.get_gamma_ratio_data()
        
        # 添加新数据
        states_data.append([timestamp, state])
        confidence_data.append([timestamp, confidence])
        delta_data.append([timestamp, delta_ratio])
        theta_data.append([timestamp, theta_ratio])
        alpha_data.append([timestamp, alpha_ratio])
        beta_data.append([timestamp, beta_ratio])
        gamma_data.append([timestamp, gamma_ratio])
        
        # 保存数据
        session.set_states_data(states_data)
        session.set_confidence_data(confidence_data)
        session.set_delta_ratio_data(delta_data)
        session.set_theta_ratio_data(theta_data)
        session.set_alpha_ratio_data(alpha_data)
        session.set_beta_ratio_data(beta_data)
        session.set_gamma_ratio_data(gamma_data)
        
        session.save()
        return True
    
    async def add_raw_eeg_data(self, session_id: str, room_id: str,
                              timestamp: datetime, channels_data: Dict[int, List],
                              signal_quality: float = None, battery_level: int = None) -> bool:
        """
        添加原始脑波数据到会话记录中
        
        Args:
            session_id: 会话ID
            room_id: 房间ID
            timestamp: 数据时间戳
            channels_data: 通道数据字典 {1: [data], 2: [data], ...}
            signal_quality: 信号质量
            battery_level: 电池电量
            
        Returns:
            bool: 是否添加成功
        """
        try:
            # 获取会话记录
            session = await self.get_session_by_id(session_id)
            if not session:
                self.logger.error(f"会话不存在: {session_id}")
                return False
            
            # 转换时间戳为毫秒
            timestamp_ms = int(timestamp.timestamp() * 1000)
            
            # 添加各通道原始数据
            for channel, data in channels_data.items():
                if 1 <= channel <= 8:
                    # 获取现有数据
                    existing_data = session.get_raw_channel_data(channel)
                    # 添加新数据点
                    existing_data.append([timestamp_ms, data])
                    # 保存更新后的数据
                    session.set_raw_channel_data(channel, existing_data)
            
            # 添加信号质量数据
            if signal_quality is not None:
                quality_data = session.get_signal_quality_data()
                quality_data.append([timestamp_ms, signal_quality])
                session.set_signal_quality_data(quality_data)
            
            # 添加电池电量数据
            if battery_level is not None:
                battery_data = session.get_battery_level_data()
                battery_data.append([timestamp_ms, battery_level])
                session.set_battery_level_data(battery_data)
            
            # 保存会话
            session.save()
            return True
        except Exception as e:
            self.logger.error(f"保存原始数据失败: {e}")
            return False
    
    async def get_session_analysis(self, session_id: str) -> Dict[str, Any]:
        """
        获取会话分析结果
        
        Args:
            session_id: 会话ID
            
        Returns:
            Dict[str, Any]: 分析结果
        """
        session = await self.get_session_by_id(session_id)
        if not session:
            return {}
        
        # 获取所有脑波数据
        brainwave_data = session.get_all_brainwave_data()
        
        # 计算统计信息
        analysis = {
            'session_info': {
                'session_id': session.session_id,
                'room_id': session.room_id,
                'start_time': session.start_time,
                'end_time': session.end_time,
                'total_seconds': session.total_seconds
            },
            'summary': {
                'dominant_state': session.dominant_state,
                'avg_confidence': float(session.avg_confidence) if session.avg_confidence else None,
                'deep_sleep_duration': session.deep_sleep_duration,
                'light_sleep_duration': session.light_sleep_duration,
                'awake_duration': session.awake_duration,
                'description': session.description
            },
            'brainwave_data': brainwave_data
        }
        
        # 计算脑波比例统计
        if brainwave_data['delta_ratio']:
            delta_values = [ratio for _, ratio in brainwave_data['delta_ratio']]
            analysis['brainwave_stats'] = {
                'delta': {
                    'avg': sum(delta_values) / len(delta_values),
                    'min': min(delta_values),
                    'max': max(delta_values)
                }
            }
            
            # 计算其他波段统计
            for wave_type in ['theta', 'alpha', 'beta', 'gamma']:
                wave_data = brainwave_data[f'{wave_type}_ratio']
                if wave_data:
                    values = [ratio for _, ratio in wave_data]
                    analysis['brainwave_stats'][wave_type] = {
                        'avg': sum(values) / len(values),
                        'min': min(values),
                        'max': max(values)
                    }
        
        return analysis
    
    async def get_room_statistics(self, room_id: str, days: int = 30) -> Dict[str, Any]:
        """
        获取房间统计信息
        
        Args:
            room_id: 房间ID
            days: 统计天数
            
        Returns:
            Dict[str, Any]: 统计信息
        """
        start_date = datetime.now() - timedelta(days=days)
        
        sessions = list(
            SleepMonitoringRecord.select()
            .where(
                (SleepMonitoringRecord.room_id == room_id) &
                (SleepMonitoringRecord.start_time >= start_date)
            )
        )
        
        if not sessions:
            return {
                'room_id': room_id,
                'period_days': days,
                'total_sessions': 0
            }
        
        # 计算统计信息
        total_duration = sum(s.total_seconds for s in sessions if s.total_seconds)
        avg_duration = total_duration / len(sessions) if sessions else 0
        
        # 统计主要状态分布
        state_counts = {}
        for session in sessions:
            if session.dominant_state:
                state_counts[session.dominant_state] = state_counts.get(session.dominant_state, 0) + 1
        
        # 计算平均置信度
        confidences = [float(s.avg_confidence) for s in sessions if s.avg_confidence]
        avg_confidence = sum(confidences) / len(confidences) if confidences else None
        
        return {
            'room_id': room_id,
            'period_days': days,
            'total_sessions': len(sessions),
            'total_duration_seconds': total_duration,
            'avg_duration_seconds': avg_duration,
            'state_distribution': state_counts,
            'avg_confidence': avg_confidence,
            'first_session': sessions[-1].start_time if sessions else None,
            'last_session': sessions[0].start_time if sessions else None
        }
    
    async def update_session_description(self, session_id: str, description: str) -> bool:
        """
        更新会话描述
        
        Args:
            session_id: 会话ID
            description: 描述内容
            
        Returns:
            bool: 是否更新成功
        """
        session = await self.get_session_by_id(session_id)
        if not session:
            return False
        
        session.description = description
        session.save()
        return True
    
    async def delete_session(self, session_id: str) -> bool:
        """
        删除会话记录
        
        Args:
            session_id: 会话ID
            
        Returns:
            bool: 是否删除成功
        """
        session = await self.get_session_by_id(session_id)
        if not session:
            return False
        
        # 删除会话记录（包含所有原始数据和分析数据）
        session.delete_instance()
        
        self.logger.info(f"删除会话记录: {session_id}")
        return True